using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace xna_game_engine.source
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Level
    {
        // Members
        private Texture2D mLevelTexture;
        private Vector2 mPlayerStart;
        private List<Vector2> mEnemyStarts;
        private Color[] mLevelData;
        private int mVerticalTopLimit;
        private int mVerticalBottomLimit;

        // Color key data
        private static Color ENEMY_COL  = Color.Red;
        private static Color PLAYER_COL = Color.Blue;
        private static Color IGNORE_COL = Color.Black;
        private static Color VERT_LIM_T = Color.Yellow;
        private static Color VERT_LIM_B = Color.Cyan;


        // Functions
        public Level()
        {
            mPlayerStart = Vector2.Zero;
            mEnemyStarts = new List<Vector2>();
            mVerticalBottomLimit = mVerticalTopLimit = 0;
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public void Initialize()
        {
        }

        public void LoadContent()
        {
            mLevelTexture = GameGlobals.Content.Load<Texture2D>("levels//level1");
            mLevelData = new Color[mLevelTexture.Height * mLevelTexture.Width];
            mLevelTexture.GetData<Color>(mLevelData, 0, mLevelTexture.Height * mLevelTexture.Width);
            GrabPertinentLevelInfo();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public void Update(GameTime gameTime)
        {
        }

        public void Draw()
        {
            GameSystems.Graphics.DrawImage(mLevelTexture, Vector2.Zero, Color.White);
        }

        private void GrabPertinentLevelInfo()
        {
            for (int i = 0; i < mLevelData.Count<Color>(); i++)
            {
                if (mLevelData[i] == PLAYER_COL)
                {
                    // we have found the player start
                    mPlayerStart = ConvertIndexToVector2(i);
                    mLevelData[i] = Color.Black;
                    //break;
                }
                else if (mLevelData[i] == ENEMY_COL)
                {
                    mEnemyStarts.Add(ConvertIndexToVector2(i));
                    mLevelData[i] = Color.Black;
                }
                else if (mLevelData[i] == VERT_LIM_T)
                {
                    mVerticalTopLimit = (int)ConvertIndexToVector2(i).Y;
                    mLevelData[i] = Color.Black;
                }
                else if (mLevelData[i] == VERT_LIM_B)
                {
                    mVerticalBottomLimit = (int)ConvertIndexToVector2(i).Y;
                    mLevelData[i] = Color.Black;
                }
            }
            mLevelTexture.SetData<Color>(mLevelData);
        }

        private Vector2 ConvertIndexToVector2(int index)
        {
            int row = (int)Math.Floor((double)(index / mLevelTexture.Width)); //GetRowFromIndex(index);
            int col = index - (row * mLevelTexture.Width);
            return new Vector2(col, row);
        }

        // Properties
        public Vector2 PlayerStart
        {
            get { return mPlayerStart; }
        }

        public List<Vector2> EnemyStarts
        {
            get { return mEnemyStarts; }
        }

        public int VerticalTop
        {
            get { return mVerticalTopLimit; }
        }

        public int VerticalBottom
        {
            get { return mVerticalBottomLimit; }
        }
    }
}